const webpack = require("webpack")
// node 的 path 模块
const path = require('path') 
const { ProgressPlugin } = require('webpack');
// 分析打包后资源文件
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
// 分析unused exports 需要设置为true，production下默认是true
const DeadCodePlugin = require('webpack-deadcode-plugin');


// 清空 打包目录
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// HtmlWebpackPlugin
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 复制静态资源
const CopyPlugin = require('copy-webpack-plugin');
// 自定义plugin
const pluginDemo = require('./src/plugin-demo/plugin-fileList')
//common.js语法
const env = process.env.NODE_ENV;
console.log(env)
module.exports = {
  mode:'development', // *开发环境  production 生产环境
  
  context: path.resolve(__dirname, './src'), // *基础目录，绝对路径，用于从配置中解析入口点(entry point)和 加载器(loader)。该配置会影响入口和loaders的解析，入口和loaders的相对路径会以context的配置作为基准路径，这样，你的配置会独立于CWD（current working directory 当前执行路径）
  
  resolve: {
    alias: {
        '@': path.resolve(__dirname, 'src'),  // 别名
     
    },
    modules: ["node_modules"] , //*解析模块时，如果遇到导入语句，```require("test")```，webpack会从下面的位置寻找依赖的模块
    extensions: [".js", ".ts"],//*当解析模块时，遇到无具体后缀的导入语句，例如```require("test")```，会依次测试它的后缀名

  },
  entry:{
      main:'./main.js', // *多入口文件依次写入： 文件名：‘相对路径’
    //home:'./home.js',
    // home: {
    //   import: './home.js',
    //   filename: 'src/home.js',
    //   dependOn: 'main',  //*共享
    //   chunkLoading: false, // *禁用按需加载的块，并将所有内容放入主块中。  代码分割
    // },
    about: {
      import: './about.js',
      filename: './src/about.js',
      // dependOn: 'main',
      // chunkLoading: 'jsonp',
      // asyncChunks: true, // *创建按需加载的异步块。，需要使用 optimization.splitChunks 选项，并将其设置为一个对象。在该对象中，可以使用 cacheGroups 属性来定义各个分组的条件和参数。
      layer: 'name of layer', // *为入口点设置图层
    },

  },
  output:{

      // assetModuleFilename: 'assets/[name][hash][ext][query]',// *与 output.filename 相同，不过应用于 Asset Modules(资源模块，前提需要理解 webpack编译过程)。 具体需要配合rules详细请看文档outPut/assetModuleFilename.md

      
      path:path.resolve(__dirname,'dist'),
      pathinfo:true, //*webpack 在 bundle 中引入「所包含模块信息」的相关注释 对于在开发环境(development)下阅读生成代码时，虽然通过这些注释可以提供有用的数据信息，但在生产环境(production)下，不应该使用。
      publicPath:'',

      filename:'[name].[contenthash:8].bundle.js',

      sourceMapFilename:'[name].[contenthash:8].map.js',
      chunkFilename: '[name].[contenthash]chunk.js',
      //[id]	此 chunk 的 ID
      //* [name]	如果设置，则为此 chunk 的名称，否则使用 chunk 的 ID
      //* [chunkhash]	此 chunk 的 hash 值，包含该 chunk 的所有元素
      //* [contenthash]	此 chunk 的 hash 值，只包括该内容类型的元素（受 optimization.realContentHash 影响）
      asyncChunks:true,// 创建按需加载的异步 chunk。
      // module:true,
      library: {
       
        type:'var', //  module类型不要在此处指定“名称”
        name:'MyLib'
      }, //* https://www.webpackjs.com/configuration/output/#outputlibrary
      // libraryTarget: 'umd', //* 使用library.type 代理这个属性，这个未来即将放弃
      // auxiliaryComment:'Test Comment',  //*在和 output.library 和 output.libraryTarget 一起使用时，此选项允许用户向导出容器(export wrapper)中插入注释。要为 libraryTarget 每种类型都插入相同的注释，将 auxiliaryComment 设置为一个字符串：
      devtoolFallbackModuleFilenameTemplate: 'fallback-[absoluteResourcePath]',  //*用于指定 Source Map 文件中无法找到源代码的模块时，如何生成替代的文件名。
      // devtoolModuleFilenameTemplate: (info) => {
      //   return `webpack:///${info.resourcePath}?${info.loaders}`;
      // },
  },
  devtool:"source-map", // *调试配置
  //* 1. source map 应在开发环境中使用，作为一种调试手段
  //* 2. source map 不应该在生产环境中使用，source map的文件一般较大，不仅会导致额外的网络传输，还容易暴露原始代码。即便要在生产环境中使用source map，用于调试真实的代码运行问题，也要做出一些处理规避网络传输和代码暴露的问题。
  experiments: {  // *实验特性
    layers: true,
    
    // outputModule: true, //* 配合libary.type为 module使用
    //backCompat: true, //*为许多 webpack 4 api 启用后向兼容层，并发出弃用警告。
  },
  // target:'web', //*webpack 能够为多种环境或 target 构建编译。https://www.webpackjs.com/configuration/target/
  // *设置打包结果最终要运行的环境，常用值有

  //* - web: 打包后的代码运行在web环境中
  //* - node：打包后的代码运行在node环境中
  // *- 其他：https://www.webpackjs.com/configuration/target/
  externals: {
    jquery: "$",
    lodash: "_"
  }, //* 从最终的bundle中排除掉配置的配置的源码，例如，入口模块是 这比较适用于一些第三方库来自于外部CDN的情况，这样一来，即可以在页面中使用CDN，又让bundle的体积变得更小，还不影响源码的编写
  // stats:{
  //   warnings:false,
  //   warningsCount:false,
  //   // modules: false,
  //   // hash: false,
  // },//*stats控制的是构建过程中控制台的输出内容
  module:{
   
    rules:[
      // {
      //   test:/main\.js$/, //*匹配模块路径
      //   use:[
      //     {
      //       loader:"./loaders-demo/test-loaders", // ./loaders-demo/test-loaders? changeVal=未知数 query 格式
      //       options:{
      //         changeVal:'未知数'
      //       }
      //     }, // *加载器
          
      //   ], // *匹配到值后使用哪些加载器
      // }, // *规则一 每个规则都是一个对象
      {
        test:/\main.js$/, //*匹配模块路径
        use:["./loaders-demo/test-loaders1","./loaders-demo/test-loaders2"],
        enforce:'pre'
      },
      {
        test:/\.css$/i, //*匹配模块路径
        use:[
          // MiniCssExtractPlugin.loader,
          "style-loader",
          {
            loader:"css-loader",
            options:{
              modules:{
                localIdentName:"[name]-[hash:5]"
              }
            }
          }],  // css变成 导出字符串 代码
      },
      {
        test:/\.(scss)|(sass)$/i, //*匹配模块路径
        use:[ "style-loader",
        {
          loader:"css-loader",
          options:{
            modules:{
              localIdentName:"[name]-[hash:5]"
            }
          }
        },"sass-loader"]
      },
      {
        test:/\.(pcss)|(sss)|(postcss)$/i, //*匹配模块路径
        use:[ "style-loader",
        {
          loader:"css-loader",
          options:{
            modules:{
              localIdentName:"[name]-[hash:5]"
            }
          }
        },"postcss-loader"]
      },
      {
        test:/\.(png)|(jpg)|(jpeg)|(gif)$/, //*匹配模块路径
        use:[{
         loader: "./loaders-demo/img-loader",
         options: {
          limit: 3000, //*3000字节以上使用图片，3000字节以内使用base64
          filename: "img-[contenthash:5].[ext]"
        }
      }],
        
      },
      // {
      //   test:/\.js$/, //*匹配模块路径
      //   use:["./loaders-demo/test-loaders3","./loaders-demo/test-loaders4"]
      // }
    ], //* 匹配的匹配规则
    // noParse: /jquery|lodash/, //*不要解析某个模块 不解析正则表达式匹配的模块，通常用它来忽略那些大型的单模块库，以提高**构建性能**
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
          defaultVendors: {
              chunks: 'all',
              test: /[\\/]node_modules[\\/]/,
              name: 'vendors',
              priority: -10,
          },
      }
  },
  usedExports: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      inject:'body',  // 插入那个标签下
      filename: 'index.html',  // 生成文件名
      scriptLoading:'blocking',  // 加载方式
      template:'../public/index.html',  // 模板
      chunks:['main']  // 指定要包含在 HTML 文件中的代码块 (chunk)。如果设置为空数组，则不添加任何代码块。如果未指定，则默认情况下将包含所有代码块。

    }),
    new HtmlWebpackPlugin({
      inject:'body',
      filename: 'about.html',
      scriptLoading:'blocking',
      template:'../public/index.html',
      chunks:['about']
    }),
    new CopyPlugin({
      patterns:[
        { from: '../public/img', to: 'img' },
        { from: '../public/css', to: 'css' },
      ]
    }),
    new CleanWebpackPlugin(
      {
        cleanOnceBeforeBuildPatterns: ['**/*', '!**/*.html'],
      }
    ), //* 如果你的源代码比较大且构建时间比较长，为了优化开发体验，你可能希望在开始构建前手动清空输出目录。你可以通过在 package.json 中添加一个 npm 脚本来实现这一点，例如： rimraf dist && webpack --mode production
      new pluginDemo(),
      new webpack.DefinePlugin({   // 定义常量
        PI: `Math.PI`, // const PI = Math.PI
        VERSION: `"1.0.0"`, // VERSION = "1.0.0"
        DOMAIN: JSON.stringify("wsy.com")  // DOMAIN = "duyi.com"
    }),
    new webpack.BannerPlugin({
        banner: `
        hash:[hash]
        chunkhash:[chunkhash]
        name:[name]
        author:wangshunyu
        corporation:FEwsy
        `
    }),
    new webpack.ProvidePlugin({
        $: 'jquery',
        _: 'lodash'
    })

      // new BundleAnalyzerPlugin(),
    //   new DeadCodePlugin({
    //     patterns: [
    //         '/**/*', // 只扫描src路径下所有文件
    //     ],
    //     // exclude: [
    //     //     './**/mapping.xml',
    //     //     './**/*.md',
    //     // ],
    //     log: "none", // 不输出log
    //     exportJSON: `./analysis` // 结果生成到analysis路径下
    // })


  ],
  devServer:{
    host: 'localhost',
    port:8000,
    open:false,// *告诉 dev-server 在服务器已经启动后打开浏览器。设置其为 true 以打开你的默认浏览器。
    proxy: {
      '/api': {
        target:'https://demo-api.apipost.cn',
        changeOrigin: true, //更改请求头中的host和origin
      // secure: false // 返回 null 或 undefined 以继续使用代理处理请求。返回 false 会为请求产生 404 错误。      返回提供服务的路径，而不是继续代理请求。
      },
      
      
    },
    

    
  },
  stats: {
  
 
    assets: false,
    builtAt: true, // 显示构建日期和时间
    colors: true, // 将控制台输出编码为颜色
    // modules: false,
    // moduleAssets: false,
    
    // children: false,
    // chunks: false,
    // chunkModules: false,
    // entrypoints:false,
  },
  



}
